package com.boarsoft.boar.code.bean.action;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.boarsoft.bean.ReplyInfo;
import com.boarsoft.boar.code.bean.biz.BeanInfoBiz;
import com.boarsoft.boar.code.bean.biz.BeanPropBiz;
import com.boarsoft.boar.code.bean.biz.BeanPropTreeBiz;
import com.boarsoft.boar.code.entity.BeanInfo;
import com.boarsoft.boar.code.entity.BeanProp;
import com.boarsoft.boar.code.entity.BeanPropTree;
import com.boarsoft.common.Util;
import com.boarsoft.common.dao.PagedResult;

@RestController
@RequestMapping(value = "/bean/prop")
public class BeanPropAction {
	@Autowired
	private BeanPropTreeBiz beanPropTreeBiz;

	@Autowired
	private BeanPropBiz beanPropBiz;

	@Autowired
	private BeanInfoBiz beanInfoBiz;

	/**
	 * 根据类型递归查询属性列表
	 * 
	 * @param beanType
	 *            bean类型
	 * @param type
	 *            type
	 * @param key
	 *            查询的key值
	 * @param recursively
	 *            是否递归查询属性的属性
	 * @return 查询列表信息
	 */
	@RequestMapping(value = "/list.do")
	// @Authorized(code = "com.list")
	public ReplyInfo<Object> list(String beanType, String type, String key, boolean recursively, int pageNo, int pageSize) {
		List<BeanPropTree> beanPropTrees = new ArrayList<>();
		// 如果类型传入，则查询该类型下所有bean
		if (Util.strIsNotEmpty(type)) {
			beanPropTrees = getBeanPropTreeByType(type);
			return new ReplyInfo<>(true, //
					new PagedResult<>(beanPropTrees.size(), beanPropTrees, pageNo, pageSize));
		}
		// 如果beanType也为空，则查询beanPropTree已有数据
		if (Util.strIsEmpty(beanType)) {
			beanPropTrees = getBeanPropTreeByType(null);
			return new ReplyInfo<>(true, //
					new PagedResult<>(beanPropTrees.size(), beanPropTrees, pageNo, pageSize));
		}
		String beanId = this.getBeanIdByType(beanType);
		if (Util.strIsEmpty(beanId)) {
			return new ReplyInfo<>(false, "根据type获取beanId失败");
		}
		this.flushBeanPropTree(beanId, beanType);
		if (recursively) {
			beanPropTrees = beanPropTreeBiz.findBeanPropByBeanId(beanId, key, null);
		} else {
			beanPropTrees = beanPropTreeBiz.findBeanPropByBeanId(beanId, key, "this");
		}
		return new ReplyInfo<>(true, new PagedResult<>(beanPropTrees.size(), beanPropTrees, pageNo, pageSize));

	}

	private List<BeanPropTree> getBeanPropTreeByType(String type) {
		return beanPropTreeBiz.findBeanPropByType(type);

	}

	/**
	 * 更具类型查询beanId
	 * 
	 * @param type
	 *            类型
	 * @return String
	 */
	private String getBeanIdByType(String type) {
		List<BeanInfo> beanInfos = beanInfoBiz.findBeanInfoByType(type);
		if (CollectionUtils.isEmpty(beanInfos)) {
			return null;
		}
		return beanInfos.get(0).getId();
	}

	/**
	 * 根据beanId查询是否有数据，若没有则从bean_prop中导入
	 *
	 * @param beanId
	 *            beanId
	 */
	private void flushBeanPropTree(String beanId, String beanType) {
		List<BeanPropTree> beanPropTreeList = beanPropTreeBiz.findBeanPropByBeanId(beanId, null, null);
		if (CollectionUtils.isEmpty(beanPropTreeList)) {
			List<BeanPropTree> bTrees = new ArrayList<>();
			List<BeanPropTree> beanPropTreeList1 = this.getAutoBeanPropTree(bTrees, "this", beanId, beanType);
			this.saveBeanPropTree(beanPropTreeList1);
		}
	}

	/**
	 * 保存信息列表
	 * 
	 * @param beanPropTreeList1
	 *            prop信息列表
	 */
	private void saveBeanPropTree(List<BeanPropTree> beanPropTreeList1) {
		if (!CollectionUtils.isEmpty(beanPropTreeList1)) {
			beanPropTreeList1.forEach(beanPropTree -> {
				beanPropTreeBiz.save(beanPropTree);
			});
		}
	}

	/**
	 * 递归获取beanId下所有属性及属性的属性信息
	 * 
	 * @param bTrees
	 *            BeanPropTree列表
	 * @param obj
	 *            当前对象
	 * @param beanId
	 *            beanId
	 * @return List<BeanPropTree>
	 */
	private List<BeanPropTree> getAutoBeanPropTree(List<BeanPropTree> bTrees, String obj, String beanId, String beanType) {
		List<BeanProp> beanPropList = beanPropBiz.findBeanPropByBeanId(beanId, null);
		if (CollectionUtils.isEmpty(beanPropList)) {
			return bTrees;
		}
		List<BeanPropTree> beanPropTreeList = new ArrayList<>();
		beanPropList.forEach(beanProp -> {
			// 取beanInfo的类型
			BeanPropTree beanPropTree = new BeanPropTree();
			beanPropTree.setType(beanProp.getType());
			beanPropTree.setName(beanProp.getName());
			beanPropTree.setBeanId(beanProp.getBeanId());
			beanPropTree.setModifier(beanProp.getModifier());
			beanPropTree.setPath(obj);
			beanPropTree.setBeanType(beanType);
			beanPropTreeList.add(beanPropTree);
		});
		bTrees.addAll(beanPropTreeList);
		for (BeanProp beanProp : beanPropList) {
			// 如果是复合类型
			if (isCompoundType(beanProp.getType())) {
				List<BeanInfo> beanInfos = beanInfoBiz.findBeanInfoByType(beanProp.getType());
				if (CollectionUtils.isEmpty(beanInfos)) {
					continue;
				}
				this.getAutoBeanPropTree(bTrees, obj.concat(".").concat(beanProp.getName()), beanInfos.get(0).getId(),
						beanType);
			}
		}
		return bTrees;
	}

	private boolean isCompoundType(String type) {
		if (type.startsWith("java.")) {
			return false;
		}
		if ("int".equals(type) || "long".equals(type) || "short".equals(type) || "byte".equals(type) || "char".equals(type)
				|| "float".equals(type) || "double".equals(type) || "boolean".equals(type)) {
			return false;
		}
		return !type.contains("[") && !type.contains("(") && !type.contains("<") && !type.contains("{");
	}
	@RequestMapping(value = "/findPropType.do")
	public String findPropType(String name,String beanClass){
		String propType = beanPropBiz.findPropType(name, beanClass);
		return propType;
	}
	@RequestMapping(value = "/findPropTypeTree.do")
	public Map<String,String> findPropTypeTree(String beanClass){
		Map<String,String> map = new HashMap<>();
		map = beanPropBiz.findPropTypeTree(map,beanClass);
		return map;
	}

}
